<template>
  <div class="debug">
    <div class="debug-view">
      <div class="debug-view-tabs">
        <t-tabs v-model="debugTabsValue" theme="card">
          <t-tab-panel :value="0" label="搜索测试" :destroy-on-hide="false">
            <div class="scrollable-container" :style="getHeightStyle">
              <t-table
                row-key="index"
                :data="searchData.list"
                :columns="columns"
                cell-empty-content="-"
                :async-loading="isRun ? 'loading' : ''"
                lazy-load
                stripe
              >
                <template #operation="{ row }">
                  <t-link theme="primary" @click="onOpenTools(row)">检查</t-link>
                </template>
              </t-table>
            </div>
          </t-tab-panel>
          <t-tab-panel
            v-if="searchData.resultData[0] && searchData.resultData[0].bookUrl"
            :value="1"
            label="详情测试"
            :destroy-on-hide="false"
          >
            <div class="scrollable-container" :style="getHeightStyle">
              <t-table
                row-key="index"
                :data="bookInfoData.list"
                :columns="columns"
                cell-empty-content="-"
                :async-loading="isRun ? 'loading' : ''"
                lazy-load
                stripe
              >
                <template #operation="{ row }">
                  <t-link theme="primary" @click="onOpenTools(row)">检查</t-link>
                </template>
              </t-table>
            </div>
          </t-tab-panel>
          <t-tab-panel
            :value="2"
            label="章节测试"
            :destroy-on-hide="false"
            :disabled="searchData.resultData.length === 0 || (searchData.resultData && !searchData.resultData[0].url)"
          >
            <div class="scrollable-container" :style="getHeightStyle">
              <t-table
                row-key="index"
                :data="chapterData.list"
                :columns="columns"
                cell-empty-content="-"
                :async-loading="isRun ? 'loading' : ''"
                lazy-load
                stripe
              >
                <template #operation="{ row }">
                  <t-link theme="primary" @click="onOpenTools(row)">检查</t-link>
                </template>
              </t-table>
            </div>
          </t-tab-panel>
          <t-tab-panel
            :value="3"
            label="正文测试"
            :destroy-on-hide="false"
            :disabled="chapterData.resultData.chapterList.length === 0"
          >
            <div class="scrollable-container" :style="getHeightStyle">
              <t-table
                row-key="index"
                :data="contentData.list"
                :columns="columns"
                cell-empty-content="-"
                :async-loading="isRun ? 'loading' : ''"
                lazy-load
                stripe
              >
                <template #operation="{ row }">
                  <t-link theme="primary" @click="onOpenTools(row)">检查</t-link>
                </template>
              </t-table>
            </div>
          </t-tab-panel>
        </t-tabs>
        <div class="debug-view-option">
          <div class="debug-view-option__left">
            <span class="debug-view-option__left__text">共 {{ getRequestCount }} 次请求</span>
          </div>
          <div class="debug-view-option__right">
            <t-button v-if="getVisibleJsLogData" @click="onOpenJSLog">
              <span>JS Log</span>
            </t-button>
          </div>
        </div>
        <div class="run">
          <t-tooltip content="View">
            <t-button shape="square" :disabled="isObjectEmpty(getVisibleUiData)" @click="onOpenUI">
              <steve-icon name="view" />
            </t-button>
          </t-tooltip>
          <t-tooltip content="Run">
            <t-button @click="onRun">
              <steve-icon v-if="isRun" theme="primary" name="run-stop" />
              <steve-icon v-else theme="primary" name="run" />
            </t-button>
          </t-tooltip>
        </div>
      </div>
    </div>
    <debug-visible-ui v-model:visible="visibleUI" :type="debugTabsValue" :data="getVisibleUiData" />
    <debug-tools v-model:visible="visibleTools" :data="toolsData" />
    <debug-js-log v-model:visible="visibleJsLog" :type="debugTabsValue" :data="getVisibleJsLogData" />
  </div>
</template>

<script setup lang="tsx">
import { useLocalStorage } from '@vueuse/core';
import { TableProps } from 'tdesign-vue-next';
import { computed, CSSProperties, ref } from 'vue';

import { ApiSiteBookInfo, ApiSiteChapter, ApiSiteContent, ApiSiteRequestCancel, ApiSiteSearch } from '@/api/api';
import SteveIcon from '@/components/steveIcon/index.vue';
import { localeKeys } from '@/config/global';
import DebugJsLog from '@/pages/source/edit/components/DebugJsLog.vue';
import DebugTools from '@/pages/source/edit/components/DebugTools.vue';
import DebugVisibleUi from '@/pages/source/edit/components/DebugVisibleUi.vue';
import { compressJSON, isObjectEmpty } from '@/utils/common';

// props
const props = defineProps({
  // 组件高度
  height: {
    type: Number,
    default: 0,
  },
  // 站点优势
  siteJson: {
    type: String,
    default: '{}',
  },
});

const computedStyle = getComputedStyle(document.documentElement);
const sizeXxl = computedStyle.getPropertyValue('--td-comp-size-xxl');

// 获取组件高度
const getHeightStyle = computed((): CSSProperties => {
  return {
    height: `${props.height - parseFloat(sizeXxl) * 2}px`,
  };
});

const debugTabsValue = ref(0);

// 可视UI
const visibleUI = ref(false);
const visibleTools = ref(false);
const visibleJsLog = ref(false);

const renderResponseType = (type: number) => {
  let name = '前置请求';
  if (type === 1) {
    name = '正式请求';
  } else if (type === 2) {
    name = '分页请求';
  } else if (type === 3) {
    name = '浏览器过盾';
  } else if (type === 4) {
    name = '图片验证码';
  }
  return name;
};

const getStatusInfo = (row: any) => {
  if (row.responseType > 2) {
    return <t-tag theme="success">组件请求</t-tag>;
  }

  return (
    <div>
      {row.httpStatus === 200 ? (
        <t-tag theme="success">OK 200</t-tag>
      ) : (
        <t-tag>{row.httpStatus ? row.httpStatus : '请求失败'}</t-tag>
      )}
    </div>
  );
};

// 表格columns
const columns = ref<TableProps['columns']>([
  {
    title: '序号',
    width: 60,
    cell: (h, { rowIndex }) => {
      return String(rowIndex + 1);
    },
  },
  {
    title: '类型',
    width: 90,
    cell: (h, { row }) => {
      return <t-tag>{renderResponseType(row.responseType)}</t-tag>;
    },
  },
  {
    title: '访问地址',
    cell: (h, { row }) => {
      let res: JSX.Element = <t-tag>未获得请求地址</t-tag>;
      if (row.newUrl) {
        res = (
          <div>
            <t-space size="5px">
              {row.httpStatus !== 0 && row.responseType <= 2 ? <t-tag theme="primary">{row.method}</t-tag> : ''}
              <t-tooltip content={row.newUrl}>
                <t-tag maxWidth="300px">{row.newUrl}</t-tag>
              </t-tooltip>
            </t-space>
          </div>
        );
      }
      return res;
    },
  },
  {
    title: '状态',
    width: 100,
    cell: (h, { row }) => {
      // let res: JSX.Element = (
      //   <div>
      //     {row.httpStatus === 200 ? (
      //       <t-tag theme="success">OK 200</t-tag>
      //     ) : (
      //       <t-tag>{row.httpStatus ? row.httpStatus : '请求失败'}</t-tag>
      //     )}
      //   </div>
      // );
      // if (row.responseType > 2) {
      //   res = JSX.Element = (
      //     <div>
      //       <t-tag theme="success">窗口请求</t-tag>
      //     </div>
      //   );
      // }
      return getStatusInfo(row);
    },
  },
  {
    colKey: 'operation',
    title: '操作',
    width: '100',
    foot: '-',
  },
]);

// 搜索数据
const searchData = ref({
  list: [],
  resultData: [],
  jsLog: '',
  gets: {},
});

// 详情页数据
const bookInfoData = ref({
  list: [],
  resultData: {},
  jsLog: '',
  gets: {},
});

// 章节数据
const chapterData = ref({
  list: [],
  resultData: {
    bookInfo: {},
    chapterList: [],
  },
  jsLog: '',
  gets: {},
});

// 正文数据
const contentData = ref({
  list: [],
  resultData: {},
  jsLog: '',
  gets: {},
});

// 重置searchData
const resetSearchData = () => {
  searchData.value.list = [];
  searchData.value.resultData = [];
  searchData.value.jsLog = '';
  searchData.value.gets = {};
};

// 重置详情页
const resetBookInfoData = () => {
  bookInfoData.value.list = [];
  bookInfoData.value.resultData = {};
  bookInfoData.value.jsLog = '';
  bookInfoData.value.gets = {};
};

// 重置章节数据
const resetChapterData = () => {
  chapterData.value.list = [];
  chapterData.value.resultData.chapterList = [];
  chapterData.value.resultData.bookInfo = {};
  chapterData.value.jsLog = '';
  chapterData.value.gets = {};
};

// 重置正文数据
const resetContentData = () => {
  contentData.value.list = [];
  contentData.value.resultData = {};
  contentData.value.jsLog = '';
  contentData.value.gets = {};
};

/**
 * 运行
 */
const isRun = ref(false);
const abortController = ref();
const onRun = () => {
  if (isRun.value) {
    // 运行中
    // 取消请求
    ApiSiteRequestCancel(debugTabsValue).then((data) => {
      if (data) {
        isRun.value = false;
        abortController.value.abort();
      }
    });
  } else {
    // 开始运行
    isRun.value = true;
    if (debugTabsValue.value === 0) {
      // 搜索
      searchRequest();
    } else if (debugTabsValue.value === 1) {
      // 详情页
      bookInfoRequest();
    } else if (debugTabsValue.value === 2) {
      // 章节
      chapterRequest();
    } else if (debugTabsValue.value === 3) {
      // 正文
      contentRequest();
    }
  }
};

// 搜索请求
const searchRequest = () => {
  // 先重置数据
  resetSearchData();
  resetBookInfoData();
  const keyword = useLocalStorage(localeKeys.sourceDebugSearch, '修仙');
  const { searchRequest, searchAbort } = ApiSiteSearch(keyword.value, compressJSON(props.siteJson));
  abortController.value = searchAbort;
  searchRequest
    .then((data) => {
      searchData.value.list = data.list;
      searchData.value.jsLog = data.jsLog;
      searchData.value.gets = data.gets;
      if (data.resultData) {
        searchData.value.resultData = JSON.parse(data.resultData);
      }
    })
    .finally(() => {
      isRun.value = false;
    });
};

// 详情页请求
const bookInfoRequest = () => {
  // 先重置数据
  resetBookInfoData();
  resetChapterData();

  // 获取搜索数据
  const book = searchData.value.resultData[0];

  // 开始请求
  const { bookInfoRequest, bookInfoAbort } = ApiSiteBookInfo(JSON.stringify(book), compressJSON(props.siteJson));
  abortController.value = bookInfoAbort;
  bookInfoRequest
    .then((data) => {
      bookInfoData.value.list = data.list;
      bookInfoData.value.jsLog = data.jsLog;
      bookInfoData.value.gets = data.gets;
      if (data.resultData) {
        bookInfoData.value.resultData = JSON.parse(data.resultData);
        searchData.value.resultData[0] = bookInfoData.value.resultData;
      }
    })
    .finally(() => {
      isRun.value = false;
    });
};

// 章节请求
const chapterRequest = () => {
  // 先重置数据
  resetChapterData();
  resetContentData();
  // 获取搜索数据
  const book = searchData.value.resultData[0];

  // 如果存在章节列表则需要重新赋值
  if (bookInfoData.value.resultData && bookInfoData.value.resultData.url) {
    book.url = bookInfoData.value.resultData.url;
  }

  // 开始请求
  const { chapterRequest, chapterAbort } = ApiSiteChapter(JSON.stringify(book), compressJSON(props.siteJson));
  abortController.value = chapterAbort;
  chapterRequest
    .then((data) => {
      chapterData.value.list = data.list;
      chapterData.value.jsLog = data.jsLog;
      chapterData.value.gets = data.gets;
      if (data.resultData) {
        chapterData.value.resultData = JSON.parse(data.resultData);
      }
    })
    .finally(() => {
      isRun.value = false;
    });
};

// 正文请求
const contentRequest = () => {
  // 先重置数据
  resetContentData();
  // 获取章节数据
  const chapter = chapterData.value.resultData.chapterList[0];
  const { contentRequest, contentAbort } = ApiSiteContent(JSON.stringify(chapter), compressJSON(props.siteJson));
  abortController.value = contentAbort;
  contentRequest
    .then((data) => {
      contentData.value.list = data.list;
      contentData.value.jsLog = data.jsLog;
      contentData.value.gets = data.gets;
      if (data.resultData) {
        contentData.value.resultData = JSON.parse(data.resultData);
      }
    })
    .finally(() => {
      isRun.value = false;
    });
};

// 打开测试工具
const toolsData = ref({});
const onOpenTools = (row: any) => {
  toolsData.value = row;
  visibleTools.value = true;
};

// 打开 JSLog
const onOpenJSLog = () => {
  visibleJsLog.value = true;
};

// 获取请求的数量
const getRequestCount = computed(() => {
  let count = 0;
  if (debugTabsValue.value === 1) {
    count = bookInfoData.value.list.length;
  } else if (debugTabsValue.value === 2) {
    count = chapterData.value.list.length;
  } else if (debugTabsValue.value === 3) {
    count = contentData.value.list.length;
  } else {
    count = searchData.value.list.length;
  }
  return count;
});

// 获取JSLog数据
const getVisibleJsLogData = computed(() => {
  let data = '';
  if (debugTabsValue.value === 1) {
    data = bookInfoData.value.jsLog;
  } else if (debugTabsValue.value === 2) {
    data = chapterData.value.jsLog;
  } else if (debugTabsValue.value === 3) {
    data = contentData.value.jsLog;
  } else {
    data = searchData.value.jsLog;
  }
  return data;
});

// 打开可视化视图
const onOpenUI = () => {
  visibleUI.value = true;
};

// 获取可视化视图的数据
const getVisibleUiData = computed(() => {
  let data: any;
  if (debugTabsValue.value === 1) {
    data = bookInfoData.value.resultData;
  } else if (debugTabsValue.value === 2) {
    data = chapterData.value.resultData.chapterList;
  } else if (debugTabsValue.value === 3) {
    data = contentData.value.resultData;
  } else {
    data = searchData.value.resultData;
  }
  return data;
});
</script>

<style lang="less" scoped>
.debug {
  &-view {
    flex: 1;

    .run {
      position: absolute;
      top: 0;
      right: var(--td-comp-paddingLR-s);
      z-index: 998;
      height: var(--td-comp-size-xxl);
      display: flex;
      align-items: center;
      justify-content: center;
    }

    &-option {
      height: var(--td-comp-size-xxl);
      border-top: 1px solid var(--td-component-stroke);
      padding: 0 var(--td-comp-paddingTB-s);
      display: flex;
      align-items: center;
      justify-content: space-between;

      &__left {
        &__text {
          font-size: var(--td-font-size-body-small);
          color: var(--td-gray-color-7);
        }
      }
    }

    .scrollable-container {
      overflow-y: auto;
    }
  }
}
</style>
